﻿using Nop.Admin.Models.Common;
using Nop.Admin.Models.XJ;
using Nop.Core;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.XJ;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.ExportImport;
using Nop.Services.Logging;
using Nop.Services.Media;
using Nop.Services.Security;
using Nop.Services.XJ;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Kendoui;
using System;
using System.Linq;
using System.Web.Mvc;

namespace Nop.Admin.Controllers
{
	public class ConsumablesController : BaseAdminController
	{
		#region Fields
		private readonly IPermissionService _permissionService;
		private readonly IPictureService _pictureService;
		private readonly IWorkContext _workContext;
		private readonly IOrganizationService _organizationServce;
		private readonly IDepartmentService _departmentServce;
		private readonly ICustomerService _customerService;
		private readonly IGenericAttributeService _genericAttributeService;
		private readonly IXJPlaceService _xjPlaceService;
		private readonly IXJEquipmentCategoryService _xJEquipmentCategoryService;
		private readonly IXJEquipmentService _xJEquipmentService;
		private readonly IXJEquipmentStockService _xJEquipmentStockService;
		private readonly IXJEquipmentStockLogService _xJEquipmentStockLogService;
		private readonly IXJInspectionService _xJInspectionService;
		private readonly IXJInspectionPlanService _xJInspectionPlanService;
		private readonly IXJMaintenanceService _xJMaintenanceService;
		private readonly IXJMaintenanceCommentService _xJMaintenanceCommentService;
		private readonly ICustomerActivityService _customerActivityService;
		private readonly IExportManager _exportManager;
		private readonly IImportManager _importManager;
		private readonly ILogger _logger;
		#endregion

		#region Constructors
		public ConsumablesController(IPermissionService permissionService,
			IPictureService pictureService,
			IWorkContext workContext,
			IOrganizationService organizationServce,
			IDepartmentService departmentServce,
			ICustomerService customerService,
			IGenericAttributeService genericAttributeService,
			IXJPlaceService xjPlaceService,
			IXJEquipmentCategoryService xJEquipmentCategoryService,
			IXJEquipmentService xJEquipmentService,
			IXJEquipmentStockService xJEquipmentStockService,
			IXJEquipmentStockLogService xJEquipmentStockLogService,
			IXJInspectionService xJInspectionService,
			IXJInspectionPlanService xJInspectionPlanService,
			IXJMaintenanceService xJMaintenanceService,
			IXJMaintenanceCommentService xJMaintenanceCommentService,
			ICustomerActivityService customerActivityService,
			IExportManager exportManager,
			IImportManager importManager,
			ILogger logger)
		{
			this._permissionService = permissionService;
			this._pictureService = pictureService;
			this._workContext = workContext;
			this._organizationServce = organizationServce;
			this._departmentServce = departmentServce;
			this._customerService = customerService;
			this._genericAttributeService = genericAttributeService;
			this._xjPlaceService = xjPlaceService;
			this._xJEquipmentCategoryService = xJEquipmentCategoryService;
			this._xJEquipmentService = xJEquipmentService;
			this._xJEquipmentStockService = xJEquipmentStockService;
			this._xJEquipmentStockLogService = xJEquipmentStockLogService;
			this._xJInspectionService = xJInspectionService;
			this._xJInspectionPlanService = xJInspectionPlanService;
			this._xJMaintenanceService = xJMaintenanceService;
			this._xJMaintenanceCommentService = xJMaintenanceCommentService;
			this._customerActivityService = customerActivityService;
			this._exportManager = exportManager;
			this._importManager = importManager;
			this._logger = logger;
		}
		#endregion

		#region Utilities

		[NonAction]
		protected virtual void PrepareAllCategoriesModel(ConsumablesModel model)
		{
			if (model == null)
				throw new ArgumentNullException("model");

			model.AvailableCategories.Add(new SelectMenuModel
			{
				name = "请选择",
				id = 0,
				open = true,
			});
			var categorys = _xJEquipmentCategoryService.GetAllCategorys(isConsumables: true, showHidden: false);
			foreach (var c in categorys)
				model.AvailableCategories.Add(new SelectMenuModel { name = c.Name, id = c.Id, pId = c.PId });
		}
		#endregion

		#region List
		public ActionResult Index()
		{
			return RedirectToAction("List");
		}

		public virtual ActionResult List()
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var model = new EquipmentListModel();

			return View(model);
		}

		[HttpPost]
		public virtual ActionResult ConsumablesList(DataSourceRequest command, EquipmentListModel model)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedKendoGridJson();

			var categories = _xJEquipmentService.GetAllEquipments(
				categoryId: model.SearchCategoryId,
				placeId: model.SearchPlaceId,
				pId: model.SearchPId,
				name: model.SearchName,
				pp: model.SearchManufacturer,
				gg: model.SearchSpecification,
				isConsumables: true,
				onlyStock: model.OnlyStock,
				onlyWarn: model.OnlyWarn,
				pageIndex: command.Page - 1,
				pageSize: command.PageSize);
			var gridModel = new DataSourceResult
			{
				Data = categories.Select(x =>
				{
					return x;
				}),
				Total = categories.TotalCount
			};
			return Json(gridModel);
		}
		#endregion

		#region Delete

		[HttpPost]
		public virtual ActionResult Delete(int id)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var equipment = _xJEquipmentService.GetXJEquipmentById(id);
			if (equipment == null)
				//No equipment found with the specified id
				return RedirectToAction("List");

			try
			{

				_xJEquipmentService.DeleteEquipment(equipment);

				//activity log
				_customerActivityService.InsertActivity("DeleteEquipment", "删除耗材：{0}", equipment.Name);

				SuccessNotification("删除成功");
			}
			catch (Exception ex)
			{
				ErrorNotification(ex.Message);

				return RedirectToAction("Edit", new { id });
			}
			return RedirectToAction("List");
		}

		[HttpPost]
		public virtual ActionResult ConsumablesDelete(int id)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var equipment = _xJEquipmentService.GetXJEquipmentById(id);
			if (equipment == null)
				return Json(new { result = false, msg = "不能删除" });

			try
			{
				if (equipment.Stock > 0)
					return Json(new { result = false, msg = "当前库存未处理，不能删除" });
				if (equipment.Freeze > 0)
					return Json(new { result = false, msg = "领用申请未处理，不能删除" });

				// 有库存记录的只能管理员删除
				if (!_xJEquipmentStockLogService.HasLogs(equipmentId: equipment.Id) || _workContext.CurrentCustomer.IsAdmin())
				{
					_xJEquipmentService.DeleteEquipment(equipment);

					//activity log
					_customerActivityService.InsertActivity("DeleteEquipment", "删除设施设备：{0}", equipment.Name);

					return Json(new { result = true, msg = "删除成功" });
				}
				return Json(new { result = false, msg = "不能删除" });
			}
			catch (Exception ex)
			{
				return Json(new { result = false, msg = ex.Message });
			}
			//return new NullJsonResult();
		}

		#endregion

		#region Equipments

		public virtual ActionResult AddPopup(int cId = 0)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var model = new ConsumablesModel
			{
				CategoryId = cId,
				Published = true,
			};
			//categories
			PrepareAllCategoriesModel(model);
			return View(model);
		}

		public virtual ActionResult EditPopup(int id)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var model = new ConsumablesModel();
			var equipment = _xJEquipmentService.GetXJEquipmentById(id);
			if (null != equipment)
			{
				model.Id = equipment.Id;
				model.CategoryId = equipment.CategoryId;
				model.Name = equipment.Name;
				model.Price = equipment.Price;
				model.MeanLife = equipment.MeanLife;
				model.Manufacturer = equipment.Manufacturer;
				model.Specification = equipment.Specification;
				model.Unit = equipment.Unit;
				model.DisplayOrder = equipment.DisplayOrder;
				model.StockMin = equipment.StockMin;
				model.CustomerId = equipment.CustomerId;
				model.CreatedOn = equipment.CreatedOn;
				model.Published = true;
			}
			//categories
			PrepareAllCategoriesModel(model);

			return View(model);
		}

		[HttpPost]
		[FormValueRequired("save")]
		public virtual ActionResult AddPopup(string btnId, string formId, ConsumablesModel model)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			if (ModelState.IsValid)
			{
				var equipment = new XJEquipment
				{
					CategoryId = model.CategoryId,
					Name = model.Name,
					Manufacturer = model.Manufacturer,
					Specification = model.Specification,
					Unit = model.Unit,
					//MeanLife = model.MeanLife,
					//Price = model.Price,
					DisplayOrder = model.DisplayOrder,
					StockMin = model.StockMin,
					CustomerId = _workContext.CurrentCustomer.Id,
					CreatedOn = DateTime.Now,
					IsConsumables = true,
					Published = model.Published,
				};
				_xJEquipmentService.InsertXJEquipment(equipment);

				//activity log
				_customerActivityService.InsertActivity("AddNewEquipment", "新增耗材：{0}", equipment.Name);

				_xJEquipmentCategoryService.SyncCategoryPlaces(equipment.CategoryId, _workContext.CurrentCustomer);

				ViewBag.RefreshPage = true;
				ViewBag.btnId = btnId;
				ViewBag.formId = formId;
			}

			//categories
			PrepareAllCategoriesModel(model);
			return View(model);
		}

		[HttpPost]
		[FormValueRequired("save")]
		public virtual ActionResult EditPopup(string btnId, string formId, ConsumablesModel model)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			if (ModelState.IsValid)
			{
				var equipment = _xJEquipmentService.GetXJEquipmentById(model.Id);
				if (null != equipment)
				{
					equipment.CategoryId = model.CategoryId;
					equipment.Name = model.Name;
					equipment.Manufacturer = model.Manufacturer;
					equipment.Specification = model.Specification;
					equipment.Unit = model.Unit;
					//equipment.MeanLife = model.MeanLife;
					//equipment.Price = model.Price;
					equipment.DisplayOrder = model.DisplayOrder;
					equipment.StockMin = model.StockMin;
					equipment.Published = model.Published;
					_xJEquipmentService.UpdateXJEquipment(equipment);

					//activity log
					_customerActivityService.InsertActivity("EditEquipment", "编辑耗材：{0}", equipment.Name);

					ViewBag.RefreshPage = true;
					ViewBag.btnId = btnId;
					ViewBag.formId = formId;
				}
			}

			//categories
			PrepareAllCategoriesModel(model);
			return View(model);
		}

		#endregion

		#region Export / Import

		[HttpPost, ActionName("List")]
		[FormValueRequired("exportexcel-all")]
		public virtual ActionResult ExportExcelAll(EquipmentListModel model)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var categories = _xJEquipmentService.GetAllEquipments(
				categoryId: model.SearchCategoryId,
				placeId: model.SearchPlaceId,
				pId: model.SearchPId,
				name: model.SearchName,
				pp: model.SearchManufacturer,
				gg: model.SearchSpecification,
				isConsumables: true,
				onlyStock: model.OnlyStock,
				onlyWarn: model.OnlyWarn);

			try
			{
				byte[] bytes = _exportManager.ExportConsumablesToXlsx(categories);
				return File(bytes, MimeTypes.TextXlsx, "库存明细.xlsx");
			}
			catch (Exception exc)
			{
				ErrorNotification(exc);
				return RedirectToAction("List");
			}
		}

		[HttpPost]
		public virtual ActionResult ImportFromXlsx()
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			try
			{
				var file = Request.Files["importexcelfile"];
				if (file != null && file.ContentLength > 0)
				{
					_importManager.ImportConsumablesFromXlsx(file.InputStream, _workContext.CurrentCustomer);
				}
				else
				{
					ErrorNotification("上传失败");
					return RedirectToAction("List");
				}
				SuccessNotification("上传成功");
				return RedirectToAction("List");
			}
			catch (Exception exc)
			{
				ErrorNotification(exc);
				return RedirectToAction("List");
			}
		}
		#endregion
	}
}